#include <stdio.h>
#include <unistd.h>
#include <stdint.h>
#include <string.h>

#ifdef __cplusplus
extern "C"
{
#endif
#include "Target.h"
#ifdef __cplusplus
}
#endif

typedef union UintNumber_u
{
    uint8_t u8;
    uint16_t u16;
    uint32_t u32;
} UintNumber;

void main_union()
{
    printf("[main_callback]--------------\n");
    UintNumber number;
    memset(&number, 0, sizeof(number));
    number.u8 = 0x12;
    printf("[0x12]u8:0x%X\n", number.u8);
    printf("[0x12]u16:0x%X\n", number.u16);
    printf("[0x12]u32:0x%X\n", number.u32);
    number.u16 = 0x1234;
    printf("[0x1234]u8:0x%X\n", number.u8);
    printf("[0x1234]u16:0x%X\n", number.u16);
    printf("[0x1234]u32:0x%X\n", number.u32);
    number.u32 = 0x12345678;
    printf("[0x12345678]u8:0x%X\n", number.u8);
    printf("[0x12345678]u16:0x%X\n", number.u16);
    printf("[0x12345678]u32:0x%X\n", number.u32);
}

class TempClass
{
public:
    TempClass(int id) : m_id(id){

                        };
    ~TempClass() = default;
    int printfMember(int targetID, int data)
    {
        printf("targetID:%d,TempClassID:%d,Data:%d\n", targetID, m_id, data);
        return 0;
    }
    static int printfStatic(void *opaque, int targetID, int data)
    {
        if (!opaque)
            return -1;
        reinterpret_cast<TempClass *>(opaque)->printfMember(targetID, data);
    };

private:
    int m_id;
};

int main_callback()
{
    printf("[main_callback]--------------\n");

    TargetStruct *target1 = createTarget(1);
    TargetStruct *target2 = createTarget(2);
    TargetStruct *target3 = createTarget(3);
    TargetStruct *target4 = createTarget(4);

    TempClass object1 = TempClass(1);
    TempClass object2 = TempClass(2);
    TempClass object3 = TempClass(3);
    TempClass object4 = TempClass(4);

    setCallback(target1, &TempClass::printfStatic, &object1);
    setCallback(target2, &TempClass::printfStatic, &object2);
    setCallback(target3, &TempClass::printfStatic, &object3);
    setCallback(target4, &TempClass::printfStatic, &object4);

    int index = 0;
    while (1)
    {
        if (index >= 40)
            break;

        switch (index % 4)
        {
        case 0:
            runCallback(target1, ++index);
            break;
        case 1:
            runCallback(target2, ++index);
            break;
        case 2:
            runCallback(target3, ++index);
            break;
        case 3:
        default:
            runCallback(target4, ++index);
            break;
        }
        sleep(0.1);
    }
    return 0;
}

// typedef struct TempStruct1_t
// {
//     int (*m_callback)(int);
// } TempStruct1;

// typedef struct TempStruct2_t
// {
//     int (*m_callback)(int);
//     Temp *m_object;
// } TempStruct2;

// union TempStructUnion
// {
//     TempStruct1 struct1;
//     TempStruct2 struct2;
// };

int main_union_callback()
{
    printf("[main_union_callback]--------------\n");

    return 0;
}

int main()
{
    main_union();
    main_callback();
    main_union_callback();

    printf("[main_over]--------------\n");
    printf("Hello World!\n");
    return 0;
}